package com.example.onlinemarket.fragment;

import android.os.Bundle;

import androidx.annotation.AnyThread;
import androidx.annotation.UiThread;
import androidx.appcompat.app.AlertDialog;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.example.onlinemarket.R;
import com.example.onlinemarket.adapter.RecyclerViewAdapter;
import com.example.onlinemarket.graphics.AddButton;
import com.example.onlinemarket.graphics.ReduceButton;
import com.example.onlinemarket.model.MobileOrderInfo;
import com.example.onlinemarket.model.MobileOrderItem;
import com.example.onlinemarket.model.OrderInfo;
import com.example.onlinemarket.util.ActivityUtil;
import com.example.onlinemarket.util.DialogUtil;
import com.example.onlinemarket.util.JSONUtil;
import com.example.onlinemarket.util.LogUtil;
import com.google.gson.reflect.TypeToken;
import com.mock.alipay.Callback;
import com.mock.alipay.PasswordKeypad;
import com.scwang.smart.refresh.layout.SmartRefreshLayout;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.example.onlinemarket.Application.loginUser;
import static com.example.onlinemarket.model.MobileOrderInfo.getMobileOrderInfoList;
import static com.example.onlinemarket.util.ActivityUtil.goShop;
import static com.example.onlinemarket.util.ActivityUtil.showBigImage;
import static com.example.onlinemarket.util.HttpUtil.sendHttpRequest;

public class ShoppingCartFragment extends Fragment {

    private LinearLayout tipLayout;
    private TextView tipTv;
    private RecyclerView recyclerView;
    private RecyclerViewAdapter<OrderInfo> adapter;
    private TextView totalPriceTv;
    private Button purchaseBtn;
    private SmartRefreshLayout refreshLayout;
    private ConstraintLayout confirmLayout;
    private PasswordKeypad mKeypad;
    private boolean state;

    private OnTotalPriceChangedListener totalPriceChangedListener;

    private List<OrderInfo> orderInfoList;

    public ShoppingCartFragment() {
        orderInfoList = new ArrayList<>();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override//在销毁前判断是否需要将购物车数据回传到服务器
    public void onDestroyView() {
        new Thread(() -> {
            uploadShoppingCart(false);
            loginUser = null;
        }).start();
        super.onDestroyView();
    }

    //判断提交购物车的原因isPurchased, true表示因提交订单而提交, false表示退出时发现购物车数据有变更而提交
    private void uploadShoppingCart(boolean isPurchased) {
        String shoppingCart = JSONUtil.toJson(getMobileOrderInfoList(orderInfoList), new TypeToken<List<MobileOrderInfo>>(){}.getType());
        Map<String, String> map = new HashMap<>();
        map.put("shoppingCart", shoppingCart);
        map.put("id", String.valueOf(loginUser.getUserId()));
        map.put("isPurchased", String.valueOf(isPurchased));
        if(isPurchased)// TODO: 2021/6/10
            map.put("address", loginUser.getAddress());
        sendHttpRequest("/uploadShoppingCart", "POST", map);
    }

    //初始化组件
    private void initWidgets(View view){
        recyclerView = view.findViewById(R.id.recycler_view);
        totalPriceTv = view.findViewById(R.id.tv_shopping_cart_total_price);
        purchaseBtn = view.findViewById(R.id.btn_purchase);
        refreshLayout = view.findViewById(R.id.layout_refresh);
        refreshLayout.setEnableLoadMore(false);
        tipLayout = view.findViewById(R.id.layout_tip);
        tipTv = view.findViewById(R.id.tv_shopping_cart_tip);
        adapter = getShoppingCartAdapter();
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        confirmLayout = view.findViewById(R.id.layout_shopping_cart_confirm);
        mKeypad = new PasswordKeypad();
        mKeypad.setPasswordCount(6);
        mKeypad.setCallback(new Callback() {
            @Override
            public void onForgetPassword() {
                Toast.makeText(getContext(), "忘记密码",Toast.LENGTH_LONG).show();
            }

            @Override
            public void onInputCompleted(CharSequence password) {
                new Handler().postDelayed(() -> {
                    if(password.toString().equals(loginUser.getPayPassword())) {
                        mKeypad.setPasswordState(true);
                        new Thread(() -> {
                            try {
                                Thread.sleep(1500);
                                uploadShoppingCart(true);
                                orderInfoList.clear();
                                Objects.requireNonNull(getActivity()).runOnUiThread(() -> {
                                    adapter.notifyDataSetChanged();
                                    showTip(getString(R.string.tip_no_shopping_cart));
                                    Toast.makeText(getContext(), "下单成功", Toast.LENGTH_SHORT).show();
                                });
                            } catch (InterruptedException ignored) { }
                        }).start();
                    }
                    else
                        mKeypad.setPasswordState(false, "密码输入错误");
                },1000);
            }

            @Override
            public void onPasswordCorrectly() {
                mKeypad.dismiss();
            }

            @Override
            public void onCancel() {
                Toast.makeText(getContext(), "取消了付款", Toast.LENGTH_SHORT).show();
            }
        });
    }

    //为组件设置事件监听器
    private void setWidgetsListener(){
        //增删商品数量将改变总价
        totalPriceChangedListener = new OnTotalPriceChangedListener();
        //下拉刷新
        refreshLayout.setOnRefreshListener(refreshLayout -> {
            getShoppingCart();
            refreshLayout.finishRefresh();
        });
        purchaseBtn.setOnClickListener(v -> new Thread(() -> Objects.requireNonNull(getActivity()).runOnUiThread(() -> {
            FragmentManager fragmentManager = getFragmentManager();
            if(fragmentManager!=null)
                mKeypad.show(fragmentManager, "PasswordKeypad");
        })).start());
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_shopping_cart, container, false);
        //初始化组件
        initWidgets(view);
        //为组件设置事件监听器
        setWidgetsListener();
        return view;
    }

    @Override
    public void onResume() {
        super.onResume();
        refreshLayout.autoRefresh();
        getShoppingCart();
        if(orderInfoList.size()==0)
            showTip(getString(R.string.tip_no_shopping_cart));
        else
            hideTip();
    }

    //格式化double类型，转换为小数点后两位的字符串
    public String formatDouble(double src){
        DecimalFormat decimalFormat = new DecimalFormat("#.00");
        return decimalFormat.format(src);
    }

    @AnyThread
    public void getShoppingCart(){
        if(loginUser==null){
            showTip(getString(R.string.net_error));
        }else{
            new Thread(() -> {
                Map<String, String> map = new HashMap<>();
                map.put("userId", String.valueOf(loginUser.getUserId()));
                String responseData = sendHttpRequest("/shoppingCart", "POST", map);
                if(responseData!=null&&!responseData.isEmpty()){
                    if(responseData.equals("NoShoppingCart"))
                        Objects.requireNonNull(getActivity()).runOnUiThread(() -> showTip(getString(R.string.tip_no_shopping_cart)));
                    else{
                        List<OrderInfo> orderInfos = JSONUtil.fromJsons(responseData, new TypeToken<List<OrderInfo>>(){}.getType());
                        //判断两数组是否相等，若相等则不必更新数据
                        if(!(orderInfos.containsAll(orderInfoList)&&orderInfoList.containsAll(orderInfos))){
                            orderInfoList.clear();
                            orderInfoList = orderInfos;
                            if(orderInfoList.size()==0)
                                Objects.requireNonNull(getActivity()).runOnUiThread(() -> showTip(getString(R.string.tip_no_shopping_cart)));
                            else{
                                double totalPrice = 0;
                                for(OrderInfo orderInfo: orderInfoList){
                                    for (MobileOrderItem orderItem:orderInfo.orderItemList) {
                                        orderItem.getGoodImg();
                                        totalPrice += orderItem.sellPrice * orderItem.goodNum;
                                    }
                                }
                                String totalPriceText = "总价："+formatDouble(totalPrice)+"元";
                                adapter = getShoppingCartAdapter();
                                Objects.requireNonNull(getActivity()).runOnUiThread(() -> {
                                    totalPriceTv.setText(totalPriceText);
                                    hideTip();
                                    recyclerView.setAdapter(adapter);
                                    adapter.notifyDataSetChanged();
                                });
                            }
                        }else
                            Objects.requireNonNull(getActivity()).runOnUiThread(() -> Toast.makeText(getContext(), "没有可更新的数据", Toast.LENGTH_SHORT).show());
                    }
                }else
                    Objects.requireNonNull(getActivity()).runOnUiThread(() -> showTip(getString(R.string.net_error)));
            }).start();
        }
    }

    //显示提示
    @UiThread
    private void showTip(String tipText) {
        recyclerView.setVisibility(View.INVISIBLE);
        //refreshLayout.setVisibility(View.INVISIBLE);
        tipTv.setText(tipText);
        tipLayout.setVisibility(View.VISIBLE);
        confirmLayout.setVisibility(View.INVISIBLE);
    }

    //隐藏提示，显示购物车页面
    @UiThread
    private void hideTip(){
        recyclerView.setVisibility(View.VISIBLE);
        //refreshLayout.setVisibility(View.VISIBLE);
        tipLayout.setVisibility(View.INVISIBLE);
        confirmLayout.setVisibility(View.VISIBLE);
    }

    @AnyThread
    private RecyclerViewAdapter<OrderInfo> getShoppingCartAdapter(){
        return new RecyclerViewAdapter<OrderInfo>(getContext(),
                R.layout.shopping_cart_order_item, orderInfoList) {
            @Override
            public int getLayoutId(int viewType) {
                return R.layout.shopping_cart_order_item;
            }
            @Override
            public void convert(ViewHolder holder, OrderInfo data, int pos) {
                holder.setText(R.id.iv_shopping_cart_shop_name, data.order.getShopName());
                holder.setOnClickListener(R.id.iv_shopping_cart_shop_name, v -> new Thread(() -> goShop(getActivity(), data.order.getShopId())).start());
                holder.setText(R.id.et_shopping_cart_note, data.order.getNote());
                RecyclerView recyclerView1 = holder.itemView.findViewById(R.id.recycler_view);
                recyclerView1.setLayoutManager(new LinearLayoutManager(context));
                recyclerView1.setAdapter(getShoppingCartGoodsAdapter(data.orderItemList));
                // TODO: 2021/6/11
            }
        };
    }

    private RecyclerViewAdapter<MobileOrderItem> getShoppingCartGoodsAdapter(List<MobileOrderItem> orderItemList){
        RecyclerViewAdapter<MobileOrderItem> adapter = new RecyclerViewAdapter<MobileOrderItem>(getContext(), R.layout.shopping_cart_good_item, orderItemList, totalPriceChangedListener) {
            @Override
            public int getLayoutId(int viewType) {
                return R.layout.shopping_cart_good_item;
            }
            @Override
            public void convert(ViewHolder holder, MobileOrderItem data, int position) {
                MobileOrderItem item = datas.get(position);
                holder.setText(R.id.iv_shopping_cart_good_id, String.valueOf(item.goodId));
                holder.setImage(R.id.iv_shopping_cart_good_img, item.imgPath);
                holder.setOnClickListener(R.id.iv_shopping_cart_good_img, v -> showBigImage(item.localPath));
                holder.setText(R.id.tv_shopping_cart_good_name, item.goodName);
                holder.setText(R.id.tv_shopping_cart_good_price, String.valueOf(item.sellPrice));
                TextView goodNumTv = holder.itemView.findViewById(R.id.tv_shopping_cart_good_num);
                goodNumTv.setText(String.valueOf(item.goodNum));
                ReduceButton reduceBtn = holder.itemView.findViewById(R.id.btn_shopping_cart_reduce_good_num);
                reduceBtn.setNumTv(data.goodId, data.sellPrice, goodNumTv, totalPriceChangedListener);
                AddButton addBtn = holder.itemView.findViewById(R.id.btn_shopping_cart_add_good_num);
                addBtn.setNumTv(data.goodId, data.sellPrice, goodNumTv, reduceBtn, totalPriceChangedListener);
                holder.itemView.setOnLongClickListener(view -> {
                    AlertDialog dialog = DialogUtil.getDialog(getContext(), "删除商品", "确定要将该商品从购物车中移除吗？", (dialog1, which) -> {
                        dialog1.dismiss();
                        new Thread(() -> {
                            int goodId = Integer.parseInt(((TextView)view.findViewById(R.id.iv_shopping_cart_good_id)).getText().toString());
                            listener.itemRemoved(goodId);
                        }).start();
                    });
                    dialog.show();
                    return true;
                });
            }
        };
        return adapter;
    }

    public class OnTotalPriceChangedListener{
        public void updateGoodNum(int goodId, int changedNum){
            new Thread(() -> {
                boolean isOk = false;
                for(OrderInfo orderInfo:orderInfoList){
                    if(!isOk){
                        for(MobileOrderItem item:orderInfo.orderItemList){
                            if(item.goodId==goodId){
                                item.goodNum += changedNum;
                                isOk = true;
                                break;
                            }
                        }
                    }else break;
                }
            }).start();
        }
        //重新计算总价
        public void getTotalPrice(double changedPrice){
            new Thread(() -> {
                String ls=totalPriceTv.getText().toString().replace("元","");
                double totalPrice = Double.parseDouble(ls.split("：")[1]);
                totalPrice += changedPrice;
                String totalPriceText = "总价："+formatDouble(totalPrice)+"元";
                Objects.requireNonNull(getActivity()).runOnUiThread(() -> totalPriceTv.setText(totalPriceText));
                uploadShoppingCart(false);
            }).start();
        }
        //移除某商品
        public void itemRemoved(int goodId){
            new Thread(() -> {
                boolean isOk = false;
                for(OrderInfo orderInfo:orderInfoList){
                    if(!isOk){
                        for(MobileOrderItem item:orderInfo.orderItemList){
                            if(item.goodId==goodId){
                                item.goodNum = 0;
                                isOk = true;
                                break;
                            }
                        }
                    }else break;
                }
                uploadShoppingCart(false);
                getShoppingCart();
            }).start();
        }
    }
}